﻿using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;

namespace CoreWebApiNuGet.JwtAuthentication
{
    /// <summary>
    /// Jwt鉴权实现
    /// </summary>
    public class JwtTokenAuthorityService: IJwtTokenAuthorityService
    {
        private readonly JwtIssueOptions _options;
        public JwtTokenAuthorityService(JwtIssueOptions options)
        {
            _options = options;
        }

        /// <summary>
        /// 生成Token
        /// </summary>
        /// <param name="claims"></param>
        /// <returns></returns>
        public string GenerateToken(JwtCarrier jwtCarrier)
        {
            List<Claim> claims = new List<Claim>();
            Dictionary<string, string> keyValues = JwtUtility.EntityToDictionary<JwtCarrier>(jwtCarrier);

            //单条处理用户信息
            foreach (var item in keyValues)
            {
                claims.Add(new Claim(item.Key, item.Value));
            }

            //json处理用户信息
            //claims.Add(new Claim(GetConfigJson.JWTKey, JsonConvert.SerializeObject(jwtCarrier)));

            var now = DateTime.UtcNow;
            var expires = _options.Expires;
            var issuer = _options.Issuer;
            var audience = _options.Audience;
            var signingCredentials = _options.SigningCredentials;
            var jwt = new JwtSecurityToken(
                  issuer,
                  audience,
                  claims.ToArray(),
                  now,
                  expires,
                  signingCredentials
              );
            var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
            return encodedJwt;
        }

        /// <summary>
        /// 验证Token
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public bool AuthToken(string token)
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            try
            {
                tokenHandler.ValidateToken(token, new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = _options.SigningCredentials.Key,
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidIssuer = _options.Issuer,
                    ValidAudience = _options.Audience,
                    ClockSkew = TimeSpan.Zero
                }, out var validatedToken);
                //jwtSecurityToken = (JwtSecurityToken)validatedToken; ;
            }
            catch
            {
                //jwtSecurityToken = null;
                return false;
            }
            return true;
        }
    }
}
